﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LoginCommandTests.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the LoginCommandTests type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Client.Desktop.Tests.Commands
{
    using Hisaab.Business.Interfaces;
    using Hisaab.Client.Desktop.Commands;
    using Hisaab.Client.Desktop.ViewModel;
    using Hisaab.Client.Model;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using Moq;

    /// <summary>
    /// Defines the <seealso cref="LoginCommandTests"/> type.
    /// </summary>
    [TestClass]
    public class LoginCommandTests
    {
        /// <summary>
        /// Member variable _mockManager
        /// </summary>
        private Mock<IUserManager> _mockManager;

        /// <summary>
        /// Member variable _mockViewModel
        /// </summary>
        private Mock<LoginViewModel> _mockViewModel;

        /// <summary>
        /// Tests the init.
        /// </summary>
        [TestInitialize]
        public void TestInit()
        {
            _mockManager = new Mock<IUserManager>();
            _mockViewModel = new Mock<LoginViewModel>();
        }

        /// <summary>
        /// Logins the command should not execute when user is nulls.
        /// </summary>
        [TestMethod]
        public void LoginCommandShouldNotExecuteWhenUserIsNulls()
        {
            var command = new LoginCommand(_mockViewModel.Object, _mockManager.Object);
            Assert.IsFalse(command.CanExecute(null));
        }

        /// <summary>
        /// Logins the command should not execute when user name is null.
        /// </summary>
        [TestMethod]
        public void LoginCommandShouldNotExecuteWhenUserNameIsNull()
        {
            var command = new LoginCommand(_mockViewModel.Object, _mockManager.Object);
            Assert.IsFalse(command.CanExecute(new User { UserName = null }));
        }

        /// <summary>
        /// Logins the command should not execute when user name is empty.
        /// </summary>
        [TestMethod]
        public void LoginCommandShouldNotExecuteWhenUserNameIsEmpty()
        {
            var command = new LoginCommand(_mockViewModel.Object, _mockManager.Object);
            Assert.IsFalse(command.CanExecute(new User { UserName = string.Empty }));
        }

        /// <summary>
        /// Logins the command should not execute when user name is white space.
        /// </summary>
        [TestMethod]
        public void LoginCommandShouldNotExecuteWhenUserNameIsWhiteSpace()
        {
            var command = new LoginCommand(_mockViewModel.Object, _mockManager.Object);
            Assert.IsFalse(command.CanExecute(new User { UserName = "  " }));
        }

        /// <summary>
        /// Logins the command should execute when user name is valid.
        /// </summary>
        [TestMethod]
        public void LoginCommandShouldExecuteWhenUserNameIsValid()
        {
            var command = new LoginCommand(_mockViewModel.Object, _mockManager.Object);
            Assert.IsTrue(command.CanExecute(new User { UserName = "SomeUserName" }));
        }

        /// <summary>
        /// Logins the command execute should not close view if user is null.
        /// </summary>
        [TestMethod]
        public void LoginCommandExecuteShouldNotCloseViewIfUserIsNull()
        {
            var command = new LoginCommand(_mockViewModel.Object, _mockManager.Object);
            command.Execute(null);
            _mockViewModel.Verify(x => x.CloseView(), Times.Never());
        }

        /// <summary>
        /// Logins the command execute should not close view if user is not validated.
        /// </summary>
        [TestMethod]
        public void LoginCommandExecuteShouldNotCloseViewIfUserIsNotValidated()
        {
            var command = new LoginCommand(_mockViewModel.Object, _mockManager.Object);
            const string UserName = "SomeUserName";
            _mockManager.Setup(x => x.ValidateUser(UserName, It.IsAny<string>()))
                .Returns(-1)
                .Verifiable();
            command.Execute(new User { UserName = UserName });
            _mockManager.VerifyAll();
            _mockViewModel.Verify(x => x.CloseView(), Times.Never());
        }

        /// <summary>
        /// Logins the command execute should close view if user is validated.
        /// </summary>
        [TestMethod]
        public void LoginCommandExecuteShouldCloseViewIfUserIsValidated()
        {
            var command = new LoginCommand(_mockViewModel.Object, _mockManager.Object);
            const string UserName = "SomeUserName";
            _mockManager.Setup(x => x.ValidateUser(UserName, It.IsAny<string>()))
                .Returns(101)
                .Verifiable();
            command.Execute(new User { UserName = UserName });
            _mockManager.VerifyAll();
            _mockViewModel.Verify(x => x.CloseView(), Times.Once());
        }
    }
}